#include "MCP23S08.h"
#include "driver/spi_master.h"
#include "main.h"
#include "spi.h"
#include "driver/gpio.h"
#include "string.h"
#include "lvgl.h"


#define SWAPBYTES(i) ((i>>8) | (i<<8))

spi_device_handle_t MCP23S08_spi;
//SPI传输之前会被调用
void MCP23S08_spi_transfer_callback(spi_transaction_t *t)
{

    MCP23S08_CS_Clr();
}

static SemaphoreHandle_t MCP23S08_spi_mux = NULL;

esp_err_t MCP23S08_init(void)
{
    esp_err_t ret;

	MCP23S08_spi_mux = xSemaphoreCreateRecursiveMutex();

    spi_device_interface_config_t devcfg={
        .clock_speed_hz=SPI_MCP23S08_CLOCK,//60*1000*1000,  
        .mode=0,                                //SPI mode 0
        .spics_io_num=MCP23S08_CS,               //CS pin
        .queue_size=7,                          //We want to be able to queue 7 transactions at a time
        .pre_cb=MCP23S08_spi_transfer_callback,  //Specify pre-transfer callback to handle D/C line
        //.flags=SPI_DEVICE_BIT_LSBFIRST,
    };

    ret=spi_bus_add_device(SPI_MODE, &devcfg, &MCP23S08_spi);
    if(ret!=ESP_OK)
    {
        SPI_DEBUG("MCP23S08 SPI注册失败\r\n");
    }else
    {
        SPI_DEBUG("MCP23S08 SPI注册成功\r\n");
    }
    MCP23S08_Set_Out(0x00);
    MCP23S08_Set_GPIOs(0xff);
   // MCP23S08_Set_GPIOs(0x00);
    //xTaskCreate(MCP23S08_test_task,"MCP23S08_test_task",1024*2,NULL,20,NULL);

 	return 0;
}
void  MCP23S08_test_task(void *pvParameter)
{

	while (1) 
    {

        MCP23S08_DEBUG("输出高\r\n");
        MCP23S08_Set_GPIOs(0xff);
        vTaskDelay(1000 / portTICK_PERIOD_MS); 
        MCP23S08_DEBUG("输出低\r\n");
        MCP23S08_Set_GPIOs(0x00);
        vTaskDelay(1000 / portTICK_PERIOD_MS);            

 	}
	vTaskDelete(NULL);

}

uint8_t MCP23S08_spi_data(uint8_t addr,uint8_t reg,uint8_t vol) 
{	
    esp_err_t ret;
    uint8_t rx_buf[3];
    uint8_t tx_buf[3]={addr,reg,vol};
    spi_transaction_t t;

    memset(&t, 0, sizeof(t));       //Zero out the transaction

    t.length=8*3;                     //Command is 8 bits
    t.tx_buffer=&tx_buf;               //The data is the cmd itself
    t.rxlength=8*3; 
    t.rx_buffer=&rx_buf; 
    t.user=(void*)0;                //D/C needs to be set to 0

    xSemaphoreTakeRecursive(MCP23S08_spi_mux, portMAX_DELAY);

    ret=spi_device_transmit(MCP23S08_spi, &t);  //Transmit!
    if(ret!=ESP_OK)
    {
        MCP23S08_DEBUG("通信失败\r\n");
    }else
    {
        //MCP23S08_DEBUG("通信成功\r\n");
        // for(int i=0;i<3;i++)
        // {
        //     MCP23S08_DEBUG("接收到的数据[%d]:%x\r\n",i,rx_buf[i]);
        // }

    }
    xSemaphoreGiveRecursive(MCP23S08_spi_mux);
    return rx_buf[2];
}


uint8_t MCP23S08_Set_Out(uint8_t gpios)
{
    MCP23S08_spi_data(MCP23S08_ADDR|MCP23S08_WRITE,MCP23S08_IODIR,0x00);//方向寄存器1=输入0=输出
    MCP23S08_spi_data(MCP23S08_ADDR|MCP23S08_WRITE,MCP23S08_IPOL,0x00);//输入极性1=与实际电平相反0=相同
    MCP23S08_spi_data(MCP23S08_ADDR|MCP23S08_WRITE,MCP23S08_GPIO,0xff);//通用IO端口寄存器 1=输出高0=输出低
    return 0;
}


uint8_t MCP23S08_Set_GPIOs(uint8_t gpios)
{

    uint8_t rxdata=0;
    
    MCP23S08_spi_data(MCP23S08_ADDR|MCP23S08_WRITE,MCP23S08_GPIO,gpios);//通用IO端口寄存器 1=输出高0=输出低
    //MCP23S08_spi_data(MCP23S08_ADDR|MCP23S08_WRITE,MCP23S08_OLAT,gpios);//输出锁存寄存器  1=输出高0=输出低
    //rxdata = MCP23S08_spi_data(MCP23S08_ADDR|MCP23S08_READ,MCP23S08_GPIO,0xff);
    //MCP23S08_DEBUG("接收到的数据:%x\r\n",rxdata);
    
    return 0;
}
uint8_t MCP23S08_Get_GPIOs(void)
{



    return 0;
}

